"""
@-*- coding: utf-8 -*-
@ python：python 3.8
@ 创建人员：ylx
@ 创建时间：2025/4/29 下午4:57
@ 内容：读取一个yaml文件中的某些值，目的是为了在另一个yaml文件中引用,做yaml文件的热加载
当前方法目的是做到，细化读取yaml文件中的某个字段的值,处理如果yaml文件中value值为列表时的情况

举例：在业务使用中，其他业务接口的传参需要登录接口的返回值-token
在数据层的相关业务的yaml数据文件中，该业务的入参字段-token对应的值，就不能写死
token的值是登录接口返回的，把这个token存在一个yaml文件中，比如extract.yaml，作为上下文或者其他业务会使用到的数据，方便其它业务读取使用
我们在对应的数据层的对应业务的yaml文件中这样写-token:$花括号get_extract_yaml(token)花括号

这就是我们说的热加载，依赖程序运行过程中产生的值，而不是开始的时候就直接写死

**-**实际上yaml_handler模块中get_extract_yaml_single_data方法已经实现了对yaml文件中某个值的读取
封装这个方法的目的是为了更特性化处理解决，比如说，value是一个列表，那这边我们如何取列表中的值，那我们就
要在这个get_extract_yaml_single_data方法上增加相关功能

本模块作为实现yaml文件中需要动态值时-写为$花括号方法（参数花括号，来实现动态传参的过程之一：读取存储需要数据的yaml文件方法

这里仅写了一些方法，如果需要其他的，可以结合业务继续在此模块编写
先提供这种读取-存储需要数据的yaml文件的方法，然后在apiutils模块-完成对业务层yaml文件的读取及引用变量方法的调用和值的替换-使用Python的反射机制
来实现读取业务层yaml文件时，调用对应的变量方法得到返回值后，替换原有变量占位

在yaml文件中使用${}这种写法就是用于表示变量引用或占位符

本模块：实现从yaml文件中读取某个值，并返回这个值，细化了原有yaml_handler模块中get_extract_yaml_single_data方法，提供针对值为列表时，对列表值的获取策略
"""
import random
import re
from common.yaml_hander import get_extract_yaml_single_data, read_yaml
from config import setting
from common.configparse import ConfigParse


class YamlHotLoad:
    @classmethod
    def get_extract_yaml_data(cls, node_name, out_format=None):
        """
        获取extract.yaml中的数据-丰富yaml_handler模块中-get_extract_yaml_single_data方法
        首先判断out_format是否为数字类型，如果不是就获取下一个节点的value，增加这个字段的目的是因为
        yaml文件中虽然是key value的形式，但是可能会存在嵌套，比如说 key: key:value
        也可能存在key: [1,2,3,4]这种，那你要取值的时候，针对于列表只能通过索引取值，这就是这个字段的目的
        :param node_name: extract.yaml文件中的key
        :param out_format: 若数字，为int类型，非数字，则为字符串类型
        0 随机读
        -1 读取全部数据，返回字符串格式
        -2 读取全部，返回列表格式
        其它值 按顺序读取
        :return:
        """
        data = get_extract_yaml_single_data(node_name)
        # 正则表达式含义-匹配一个字符串，它由一个可选的正负号（+ 或 -），后跟一个且仅有一个数字字符组成。
        # /d 匹配一个数字字符，等价于[0-9]
        # 合法匹配例子如“0” “+5” “-3” "5" "0"不合法匹配例子如"12" "a1" "abc" "+-2"
        if out_format is not None and bool(re.compile(r"^[+-]?\d$").match(str(out_format))):
            out_format_final = int(out_format)
            data_value = {
                out_format_final: YamlHotLoad.seq_read(data, out_format_final),
                0: random.choice(data),
                -1: ",".join(data),
                -2: ",".join(data).split(",")  # 实际这个-2 目的就是为了获取整个列表，直接写data感觉也没有什么问题
            }  # 注意这个join及split是针对字符串的方法，如果你的列表中是非字符串的，可能你的yaml文件中数据是- 1，那最后读取出来的就是列表中为int型数据，比如说int型，那就会报错
            data_res = data_value[out_format_final]

        elif out_format is None:
            data_res = get_extract_yaml_single_data(node_name)

        else:
            data_res = get_extract_yaml_single_data(node_name, out_format)

        return data_res


    @staticmethod
    def seq_read(data, randoms):
        """
        当out_format不是 0 -1 2 时是其它数字时，按顺序读取列表中的值
        比如说你要取列表的第一个值，那你输入1 按照逻辑1-1=0，那么你就取的是列表的第一个值
        :param data:
        :param randoms:
        :return:
        """
        if randoms not in [0, -1, -2]:
            return data[randoms - 1]
        else:
            return None


    @classmethod
    def get_config_ini_data(cls, section, option):
        """
        获取config层-config.ini中通用的数据，如armory_command数据
        :param section: 节点
        :param option:  选项
        :return: 对应的值
        """
        get_config_data = ConfigParse()
        res_config = get_config_data.get_value(section, option)

        return res_config


if __name__ == "__main__":
    debug = YamlHotLoad()
    res_1 = debug.get_extract_yaml_data("time")
    print(res_1)
    print(type(res_1))
    # res_1 = debug.get_extract_yaml_data("name")
    # res_2 = debug.get_extract_yaml_data("repo", -1)
    # res_5 = debug.get_extract_yaml_data("repo", "-2")
    # res_3 = debug.get_extract_yaml_data("all_group", "person_group")
    # print(res_1)
    # print(res_2)
    # print(res_3)
    # print(res_5)
    #
    #
    # path = setting.file_path["extract"]
    # res_4 = read_yaml(path)
    # print(res_4)
    # res_6 = debug.get_extract_yaml_data("id", "-1")
    # print(res_6)
    #
    # print(debug.get_config_ini_data("armory_command", "查看版本号"))
